package com.dgj.kop.client;

import java.util.HashMap;
import java.util.Map;

import org.nutz.http.Header;
import org.nutz.http.Request;
import org.nutz.http.Request.METHOD;
import org.nutz.http.Response;
import org.nutz.http.sender.PostSender;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;

import com.dgj.kop.common.KOPException;
import com.dgj.kop.common.SignUtil;
import com.dgj.utils.encode.DGJDes;
import com.dgj.utils.entries.Result;
import com.dgj.utils.net.IxionFileUploadPoster;

/**
 * @author 王贵源
 *         <p/>
 *         create at 2015年4月1日 下午2:47:09
 */
public class KOPClient {
	/**
	 * 服务地址
	 */
	private String serviceUrl;
	/**
	 * appkey
	 */
	private String appKey;
	/**
	 * 秘钥
	 */
	private String appSecret;
	/**
	 * cookie信息
	 */
	private String cookie;

	private String uuid;

	private PostSender sender;

	private int timeOut = 5000;

	public int getTimeOut() {
		return timeOut;
	}

	public void setTimeOut(int timeOut) {
		if (sender != null) {
			sender.setTimeout(timeOut);
		}
		this.timeOut = timeOut;
	}

	/**
	 * @param serviceUrl
	 * @param appKey
	 * @param appSecret
	 */
	public KOPClient(String serviceUrl, String appKey, String appSecret) {
		super();
		this.serviceUrl = serviceUrl;
		this.appKey = appKey;
		this.appSecret = appSecret;
	}

	/**
	 * @param serviceUrl
	 * @param appKey
	 * @param appSecret
	 */
	public KOPClient(String serviceUrl, String appKey, String appSecret, String uuid) {
		super();
		this.serviceUrl = serviceUrl;
		this.appKey = appKey;
		this.appSecret = appSecret;
		this.uuid = uuid;
	}

	public KOPClient(String serviceUrl, String appKey, String appSecret, int timeOut, String uuid) {
		super();
		this.serviceUrl = serviceUrl;
		this.appKey = appKey;
		this.appSecret = appSecret;
		this.timeOut = timeOut;
		this.uuid = uuid;
	}

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}

	/**
     *
     */
	public KOPClient() {
		super();
	}

	private PostSender creat(String method, Map<String, Object> params, boolean fileUpload) {
		params.put("method", method);
		Request request = Request.create(serviceUrl, METHOD.POST, params);
		Map<String, String> properties = new HashMap<String, String>();
		properties.put("method", method);

		properties.put("ak", appKey);
		properties.put("sk", appSecret);
		properties.put("length", params.size() + "");
		properties.put("sign", SignUtil.sign(method, appKey, appSecret, params.size()));
		properties.put("timestamp", System.currentTimeMillis() + "");
		// 增加ua信息
		if (Lang.isWin())
			properties.put("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko");
		else if (Lang.isAndroid)
			properties
					.put("user-agent",
							"Mozilla/5.0 (Linux; U; Android 4.4.4; zh-CN; MI 3C Build/KTU84P) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.2.467 U3/0.8.0 Mobile Safari/533.1");
		else {
			properties.put("user-agent",
					"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36");
		}
		if (cookie != null) {
			properties.put("cookie", cookie);
		}
		if (!Strings.isBlank(uuid)) {
			properties.put("uuid", uuid);// kop会话
		}
		Header header = Header.create(properties);
		request.setHeader(header);
		sender = fileUpload ? new IxionFileUploadPoster(request) : new PostSender(request);
		sender.setTimeout(timeOut);
		return sender;
	}

	public Result send(String method, Map<String, Object> params, boolean fileUpload) {
		Response response;
		try {
			response = creat(method, params, fileUpload).send();
		} catch (Exception e) {
			throw Lang.wrapThrow(e);
		}
		int status = response.getStatus();
		if (status != 200) {
			throw new KOPException("response with code: " + status);
		}
		// 处理将会话信息保持
		Header header = response.getHeader();
		if (!Strings.isBlank(header.get("Set-Cookie"))) {
			cookie = header.get("Set-Cookie");
		}
		if (!Strings.isBlank(header.get("uuid"))) {
			uuid = header.get("uuid");
		}
		try {
			return Lang.map2Object(Lang.map(DGJDes.dec(response.getContent())), Result.class);
		} catch (Exception e) {
			return Result.exception(e);
		}

	}

	public Result send(String method, Map<String, Object> params) {
		return send(method, params, false);
	}

	/**
	 * @return the cookie
	 */
	public String getCookie() {
		return cookie;
	}

	public static void main(String[] args) {
		KOPClient client = new KOPClient("http://localhost:8080/emp-web/service", "dgj", "dgj", null);
		NutMap params = NutMap.NEW();
		params.put("userName", "wangwu");
		params.put("password", 111111);
		params.put("deviceType", "ANDROID");
		System.err.println(client.send("/user/login", params));

		System.err.println(client.send("/user/logout", params));
		// client.setUuid(null);
		params.clear();

		System.err.println(client.send("/employee/buildings", params));

	}

}
